home *** CD-ROM | disk | FTP | other *** search
- /* x11_keys.c -- Event translation for X11
- Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
-
- This file is part of Jade.
-
- Jade is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- Jade is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Jade; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include "jade.h"
- #include "jade_protos.h"
-
- #include <string.h>
- #include <X11/keysym.h>
- #include <X11/Xutil.h>
-
- #ifdef SWAP_DELETE_KEYS
- # define XK_DELETE XK_BackSpace
- # define XK_BACKSPACE XK_Delete
- #else
- # define XK_DELETE XK_Delete
- # define XK_BACKSPACE XK_BackSpace
- #endif
-
- _PR void translate_event(u_long *, u_long *, XEvent *);
- _PR int cook_key(void *, u_char *, int);
- _PR bool lookup_event(u_long *, u_long *, u_char *);
- _PR bool lookup_event_name(u_char *, u_long, u_long);
-
- _PR u_long esc_code, esc_mods;
- u_long esc_code = XK_Escape, esc_mods = EV_TYPE_KEYBD;
-
- static u_long
- translate_mods(u_long mods, unsigned int state)
- {
- if(state & ShiftMask)
- mods |= EV_MOD_SHIFT;
- if(state & LockMask)
- mods ^= EV_MOD_SHIFT;
- if(state & ControlMask)
- mods |= EV_MOD_CTRL;
- if(state & Mod1Mask)
- mods |= EV_MOD_MOD1;
- if(state & Mod2Mask)
- mods |= EV_MOD_MOD2;
- if(state & Mod3Mask)
- mods |= EV_MOD_MOD3;
- if(state & Mod4Mask)
- mods |= EV_MOD_MOD4;
- if(state & Mod5Mask)
- mods |= EV_MOD_MOD5;
- if(state & Button1Mask)
- mods |= EV_MOD_BUTTON1;
- if(state & Button2Mask)
- mods |= EV_MOD_BUTTON2;
- if(state & Button3Mask)
- mods |= EV_MOD_BUTTON3;
- if(state & Button4Mask)
- mods |= EV_MOD_BUTTON4;
- if(state & Button5Mask)
- mods |= EV_MOD_BUTTON5;
- return(mods);
- }
-
- void
- translate_event(u_long *code, u_long *mods, XEvent *xev)
- {
- static Time LastClick;
- switch(xev->type)
- {
- case KeyPress:
- *mods = translate_mods(*mods, xev->xkey.state);
- if(*mods & EV_MOD_SHIFT)
- {
- /* Some keys don't have keysym at index 1, if not treat it as
- normal keysym shifted. */
- *code = XKeycodeToKeysym(x11_display, xev->xkey.keycode, 1);
- if(*code == NoSymbol)
- *code = XKeycodeToKeysym(x11_display, xev->xkey.keycode, 0);
- else
- *mods &= ~EV_MOD_SHIFT;
- }
- else
- *code = XKeycodeToKeysym(x11_display, xev->xkey.keycode, 0);
- if((*code != NoSymbol) && !IsModifierKey(*code))
- *mods |= EV_TYPE_KEYBD;
- break;
- case ButtonPress:
- if(xev->xbutton.time < (LastClick + DOUBLE_CLICK_TIME))
- *code = EV_CODE_MOUSE_CLICK2;
- else
- *code = EV_CODE_MOUSE_CLICK1;
- LastClick = xev->xbutton.time;
- goto button;
- break;
- case ButtonRelease:
- *code = EV_CODE_MOUSE_UP;
- button:
- *mods = EV_TYPE_MOUSE
- | translate_mods(*mods, xev->xbutton.state);
- switch(xev->xbutton.button)
- {
- case Button1:
- *mods |= EV_MOD_BUTTON1;
- break;
- case Button2:
- *mods |= EV_MOD_BUTTON2;
- break;
- case Button3:
- *mods |= EV_MOD_BUTTON3;
- break;
- case Button4:
- *mods |= EV_MOD_BUTTON4;
- break;
- case Button5:
- *mods |= EV_MOD_BUTTON5;
- break;
- }
- break;
- }
- }
-
- int
- cook_key(void *event, u_char *buf, int buflen)
- {
- XKeyEvent *xk = event;
- KeySym ks;
- return(XLookupString(xk, buf, buflen, &ks, NULL));
- }
-
- /*
- * Stuff to translate textual key descriptions into key codes
- */
-
- typedef struct
- {
- u_char *kd_Name;
- u_long kd_Mods;
- u_long kd_Code;
- } KeyDesc;
-
- static const KeyDesc KeyDescr[] =
- {
- "Shift", EV_MOD_SHIFT, 0,
- "SFT", EV_MOD_SHIFT, 0,
- "Ctrl", EV_MOD_CTRL, 0,
- "Control", EV_MOD_CTRL, 0,
- "CTL", EV_MOD_CTRL, 0,
- "Meta", EV_MOD_META, 0,
- "Mod1", EV_MOD_MOD1, 0,
- "Mod2", EV_MOD_MOD2, 0,
- "Amiga", EV_MOD_MOD2, 0,
- "Mod3", EV_MOD_MOD3, 0,
- "Mod4", EV_MOD_MOD4, 0,
- "LMB", EV_MOD_LMB, 0,
- "Button1", EV_MOD_BUTTON1, 0,
- "MMB", EV_MOD_MMB, 0,
- "Button2", EV_MOD_BUTTON2, 0,
- "RMB", EV_MOD_RMB, 0,
- "Button3", EV_MOD_BUTTON3, 0,
- "Button4", EV_MOD_BUTTON4, 0,
- "Button5", EV_MOD_BUTTON5, 0,
-
- "SPC", EV_TYPE_KEYBD, XK_space,
- "Space", EV_TYPE_KEYBD, XK_space,
- "Spacebar", EV_TYPE_KEYBD, XK_space,
- "TAB", EV_TYPE_KEYBD, XK_Tab,
- "RET", EV_TYPE_KEYBD, XK_Return,
- "Return", EV_TYPE_KEYBD, XK_Return,
- "ESC", EV_TYPE_KEYBD, XK_Escape,
- "Escape", EV_TYPE_KEYBD, XK_Escape,
- "BS", EV_TYPE_KEYBD, XK_BACKSPACE,
- "Backspace", EV_TYPE_KEYBD, XK_BACKSPACE,
- "DEL", EV_TYPE_KEYBD, XK_DELETE,
- "Delete", EV_TYPE_KEYBD, XK_DELETE,
- "Help", EV_TYPE_KEYBD, XK_Help,
- "Up", EV_TYPE_KEYBD, XK_Up,
- "Down", EV_TYPE_KEYBD, XK_Down,
- "Right", EV_TYPE_KEYBD, XK_Right,
- "Left", EV_TYPE_KEYBD, XK_Left,
-
- /* X defines lots of long names for these simple keys... */
- " ", EV_TYPE_KEYBD, XK_space,
- "!", EV_TYPE_KEYBD, XK_exclam,
- "\"", EV_TYPE_KEYBD, XK_quotedbl,
- "#", EV_TYPE_KEYBD, XK_numbersign,
- "$", EV_TYPE_KEYBD, XK_dollar,
- "%", EV_TYPE_KEYBD, XK_percent,
- "&", EV_TYPE_KEYBD, XK_ampersand,
- "'", EV_TYPE_KEYBD, XK_quoteright,
- "(", EV_TYPE_KEYBD, XK_parenleft,
- ")", EV_TYPE_KEYBD, XK_parenright,
- "*", EV_TYPE_KEYBD, XK_asterisk,
- "+", EV_TYPE_KEYBD, XK_plus,
- ",", EV_TYPE_KEYBD, XK_comma,
- "-", EV_TYPE_KEYBD, XK_minus,
- ".", EV_TYPE_KEYBD, XK_period,
- "/", EV_TYPE_KEYBD, XK_slash,
- ":", EV_TYPE_KEYBD, XK_colon,
- ";", EV_TYPE_KEYBD, XK_semicolon,
- "<", EV_TYPE_KEYBD, XK_less,
- "=", EV_TYPE_KEYBD, XK_equal,
- ">", EV_TYPE_KEYBD, XK_greater,
- "?", EV_TYPE_KEYBD, XK_question,
- "@", EV_TYPE_KEYBD, XK_at,
- "[", EV_TYPE_KEYBD, XK_bracketleft,
- "\\", EV_TYPE_KEYBD, XK_backslash,
- "]", EV_TYPE_KEYBD, XK_bracketright,
- "^", EV_TYPE_KEYBD, XK_asciicircum,
- "_", EV_TYPE_KEYBD, XK_underscore,
- "`", EV_TYPE_KEYBD, XK_quoteleft,
- "{", EV_TYPE_KEYBD, XK_braceleft,
- "|", EV_TYPE_KEYBD, XK_bar,
- "}", EV_TYPE_KEYBD, XK_braceright,
- "~", EV_TYPE_KEYBD, XK_asciitilde,
- "£", EV_TYPE_KEYBD, XK_sterling,
-
- /* Mouse events */
- "Click1", EV_TYPE_MOUSE, EV_CODE_MOUSE_CLICK1,
- "Click2", EV_TYPE_MOUSE, EV_CODE_MOUSE_CLICK2,
- "Off", EV_TYPE_MOUSE, EV_CODE_MOUSE_UP,
- "Move", EV_TYPE_MOUSE, EV_CODE_MOUSE_MOVE,
-
- NULL, 0, 0
- };
-
- /* Puts the integers defining the event described in DESC into CODE and
- MODS. */
- bool
- lookup_event(u_long *code, u_long *mods, u_char *desc)
- {
- u_char *str = desc;
- bool rc = TRUE;
- *code = *mods = 0;
- for(;;)
- {
- u_char buff[100];
- u_char *tmp = buff;
- u_char c = *str++;
- const KeyDesc *kd = KeyDescr;
- /* Get this one token. The first character is read separately to
- allow minus characters to be used to represent itself as well as
- to terminate a token. */
- if(c != 0)
- {
- *tmp++ = c;
- while((c = *str) && (c != '-'))
- {
- *tmp++ = c;
- str++;
- }
- }
- else
- goto error;
- *tmp = 0;
- if(*str)
- str++;
- while(kd->kd_Name)
- {
- if(!strcasecmp(kd->kd_Name, buff))
- {
- *mods |= kd->kd_Mods;
- *code = kd->kd_Code;
- if(*mods & EV_TYPE_MASK)
- goto end;
- break;
- }
- kd++;
- }
- if(!kd->kd_Name)
- {
- unsigned int ks;
- if((ks = XStringToKeysym(buff)) != NoSymbol)
- {
- *mods |= EV_TYPE_KEYBD;
- *code = ks;
- goto end;
- }
- else
- {
- error:
- cmd_signal(sym_bad_event_desc, LIST_1(string_dup(desc)));
- rc = FALSE;
- goto end;
- }
- }
- }
- end:
- return(rc);
- }
-
- /* Constructs the name of the event defined by CODE and MODS in BUF. */
- bool
- lookup_event_name(u_char *buf, u_long code, u_long mods)
- {
- /* First resolve all modifiers */
- u_long tmp_mods = mods & EV_MOD_MASK;
- const KeyDesc *kd = KeyDescr;
- u_char *name;
- while(kd->kd_Name && (tmp_mods != 0))
- {
- if((tmp_mods & kd->kd_Mods) != 0)
- {
- tmp_mods &= ~kd->kd_Mods;
- buf = stpcpy(buf, kd->kd_Name);
- *buf++ = '-';
- }
- kd++;
- }
- if(tmp_mods != 0)
- return(FALSE);
- /* Now try to find the code in our lookup table */
- tmp_mods = mods & EV_TYPE_MASK;
- #if 0
- /* Since all modifiers are at the start of the table this is
- unnecessary :-) */
- kd = KeyDescr;
- #endif
- while(kd->kd_Name)
- {
- if((kd->kd_Mods == tmp_mods) && (kd->kd_Code == code))
- {
- strcpy(buf, kd->kd_Name);
- return(TRUE);
- }
- kd++;
- }
- /* Couldn't find it here; have to go to the window-system. */
- name = XKeysymToString((KeySym)code);
- if(name)
- {
- strcpy(buf, name);
- return(TRUE);
- }
- return(FALSE);
- }
-